home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / dviselect / tfmfont.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-16  |  5.3 KB  |  248 lines

  1. /*
  2.  * Copyright (c) 1987 University of Maryland Department of Computer Science.
  3.  * All rights reserved.  Permission to copy for any purpose is hereby granted
  4.  * so long as this copyright notice remains intact.
  5.  */
  6.  
  7. #ifndef lint
  8. static char rcsid[] = "$Header: tfmfont.c,v 1.1 88/02/11 17:09:00 jim Exp $";
  9. #endif
  10.  
  11. #include <stdio.h>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include "types.h"
  15. #include "conv.h"
  16. #include "font.h"
  17. #include "tfm.h"
  18.  
  19. /*
  20.  * TFM font operations.  This defines three fonts:
  21.  *
  22.  *    box   - prints as little square boxes, outlining what TeX
  23.  *        thinks is the character.
  24.  *    blank - prints as entirely blank.
  25.  *    invis - prints as entirely blank.
  26.  *
  27.  * The first two also complain that no font is available in the
  28.  * requested size; these are intended to be used as a last resort
  29.  * so that users can always print DVI files.  You should configure
  30.  * in exactly one of box or blank.
  31.  *
  32.  * TODO:
  33.  *    base box edge widths on Conversion.c_dpi
  34.  */
  35. int    box_read(), blank_read(), invis_read();
  36. int    tfm_getgly(), tfm_rasterise(), tfm_freefont();
  37.  
  38.     /* magnifications are unused in tfm fonts */
  39. struct    fontops boxops =    /* `boxtops'?  Is this a cereal driver? */
  40.     { "box", 0.0, box_read, tfm_getgly, tfm_rasterise, tfm_freefont };
  41. struct    fontops blankops =
  42.     { "blank", 0.0, blank_read, tfm_getgly, tfm_rasterise, tfm_freefont };
  43. struct    fontops invisops =
  44.     { "invis", 0.0, invis_read, tfm_getgly, tfm_rasterise, tfm_freefont };
  45.  
  46. /*
  47.  * Local info.
  48.  */
  49. struct tfm_details {
  50.     int    tfm_edge;        /* box edge widths, in pixels */
  51.     struct    conversion tfm_conv;    /* conv. from scaled pts to pixels */
  52.     struct    tfmdata tfm_data;    /* the TFM file data */
  53. };
  54.  
  55. /*
  56.  * Get the tfm_details from font f.
  57.  */
  58. #define    ftotfm(f) ((struct tfm_details *) (f)->f_details)
  59.  
  60. extern    int errno;
  61. char    *malloc();
  62.  
  63. /*
  64.  * Read a Box font.
  65.  */
  66. static int
  67. box_read(f)
  68.     struct font *f;
  69. {
  70.  
  71.     return (do_read(f, 0, 1));
  72. }
  73.  
  74. /*
  75.  * Read a Blank font.
  76.  */
  77. static int
  78. blank_read(f)
  79.     struct font *f;
  80. {
  81.  
  82.     return (do_read(f, 1, 1));
  83. }
  84.  
  85. /*
  86.  * Read an Invisible font.
  87.  */
  88. static int
  89. invis_read(f)
  90.     struct font *f;
  91. {
  92.  
  93.     return (do_read(f, 1, 0));
  94. }
  95.  
  96. /*
  97.  * Read a TFM font.  It is blank if `blank'; complain if `complain'.
  98.  */
  99. static int
  100. do_read(f, blank, complain)
  101.     register struct font *f;
  102.     int blank, complain;
  103. {
  104.     register struct tfm_details *tfm;
  105.     FILE *fd;
  106.  
  107.     if ((fd = fopen(f->f_path, "r")) == 0)
  108.         return (-1);
  109.     if ((tfm = (struct tfm_details *) malloc(sizeof (*tfm))) == NULL)
  110.         goto fail;
  111.     if (readtfmfile(fd, &tfm->tfm_data, blank))
  112.         goto fail;
  113.     if (blank)
  114.         tfm->tfm_edge = 0;
  115.     else {
  116.         tfm->tfm_edge = 2;    /* XXX should be based on dpi */
  117.         tfm->tfm_conv = Conversion;
  118.         tfm->tfm_conv.c_fromsp *= DMagFactor(f->f_scaled);
  119.                     /* XXX !data abstraction */
  120.     }
  121.     if (FontHasGlyphs(f, tfm->tfm_data.t_hdr.th_bc,
  122.               tfm->tfm_data.t_hdr.th_ec + 1))
  123.         goto fail;
  124.     f->f_details = (char *) tfm;
  125.     (void) fclose(fd);
  126.     if (complain)
  127.         error(0, 0, "Warning: no font for %s", Font_TeXName(f));
  128.     return (0);
  129.  
  130. fail:
  131.     (void) fclose(fd);
  132.     if (tfm != NULL)
  133.         free((char *) tfm);
  134.     return (-1);
  135. }
  136.  
  137. /*
  138.  * Obtain the specified range of glyphs.
  139.  */
  140. static int
  141. tfm_getgly(f, l, h)
  142.     register struct font *f;
  143.     int l;
  144.     register int h;
  145. {
  146.     register struct tfm_details *tfm = ftotfm(f);
  147.     register struct glyph *g;
  148.     register int i;
  149.     register struct char_info_word *ci;
  150. #define    t (&tfm->tfm_data)
  151.     i32 ScaleOneWidth();
  152. #define ftop(fix) cfromSP(&tfm->tfm_conv, ScaleOneWidth(fix, f->f_dvimag))
  153.  
  154.     for (i = l; i < h; i++) {
  155.         ci = &t->t_ci[i - t->t_hdr.th_bc];
  156.         /* zero widths mark invalid characters */
  157.         if (ci->ci_width == 0)
  158.             continue;
  159.         g = f->f_gly[i];
  160.         g->g_flags = GF_VALID;
  161.         g->g_tfmwidth = t->t_width[UnSign8(ci->ci_width)];
  162.         if (tfm->tfm_edge != 0) {
  163.             g->g_xorigin = 0;
  164.             g->g_yorigin = ftop(t->t_height[T_CI_H(ci)]);
  165.             g->g_width = ftop(g->g_tfmwidth);
  166.             g->g_height = g->g_yorigin +
  167.                 ftop(t->t_depth[T_CI_D(ci)]);
  168.         }
  169.     }
  170.     return (0);
  171. #undef t
  172. }
  173.  
  174. /*
  175.  * Obtain rasters for the specified glyphs.
  176.  *
  177.  * IGNORES tfm->tfm_edge: 2 HARDCODED FOR NOW
  178.  */
  179. static int
  180. tfm_rasterise(f, l, h)
  181.     struct font *f;
  182.     int l, h;
  183. {
  184.     register struct glyph *g;
  185.     register char *p;
  186.     register int w, j, i;
  187.     struct tfm_details *tfm = ftotfm(f);
  188. #define EDGE 2
  189.  
  190.     if (tfm->tfm_edge == 0)
  191.         return;
  192. if (tfm->tfm_edge != 2) panic("tfm_rasterise");
  193.     for (i = l; i < h; i++) {
  194.         g = f->f_gly[i];
  195.         if ((g->g_flags & GF_VALID) == 0 || !HASRASTER(g))
  196.             continue;
  197.         w = (g->g_width + 7) >> 3;
  198.         p = malloc((unsigned) (g->g_height * w));
  199.         if (p == NULL)
  200.             return (-1);
  201.         g->g_raster = p;
  202.         g->g_rotation = ROT_NORM;
  203.         if (g->g_width < 2 * EDGE) {
  204.             w = 2 * EDGE - g->g_width;
  205.             for (j = g->g_height; --j >= 0;)
  206.                 *p++ = 0xf0 << w;
  207.         } else {
  208.             bzero(p, g->g_height * w);
  209.             for (j = 0; j < g->g_height;) {
  210.                 if (j < EDGE || j >= g->g_height - EDGE) {
  211.                     register int k = w;
  212.  
  213.                     while (--k > 0)
  214.                         *p++ = 0xff;
  215.                     *p++ = 0xff << ((8 - g->g_width) & 7);
  216.                     j++;
  217.                     continue;
  218.                 }
  219.                 /* the following depends on EDGE==2 */
  220.                 *p = 0xc0;
  221.                 p += w - ((g->g_width & 7) == 1 ? 2 : 1);
  222.                 *p++ |= 0xc0 >> ((g->g_width - EDGE) & 7);
  223.                 if ((g->g_width & 7) == 1)
  224.                     *p++ = 0x80;
  225.                 /* end dependencies */
  226.                 if (++j == EDGE && g->g_height >= 2 * EDGE) {
  227.                     register int n = g->g_height - EDGE;
  228.  
  229.                     p += (n - j) * w;
  230.                     j = n;
  231.                 }
  232.             }
  233.         }
  234.     }
  235.     return (0);
  236. }
  237.  
  238. /*
  239.  * Discard the font details.
  240.  */
  241. static
  242. tfm_freefont(f)
  243.     struct font *f;
  244. {
  245.  
  246.     free(f->f_details);
  247. }
  248.